#include "threadPool.h"
#include "netdisk3.h"

void *threadFunc(void * arg){
    threadPool_t * pthreadPool = (threadPool_t *)arg;
    while(1){
        // 取出任务
        pthread_mutex_lock(&pthreadPool->mutex);
        while(pthreadPool->taskQueue.queueSize == 0 && pthreadPool->exitflag == 0){
            pthread_cond_wait(&pthreadPool->cond,&pthreadPool->mutex);
        }
        if(pthreadPool->exitflag == 1){
            pthread_mutex_unlock(&pthreadPool->mutex);
            pthread_exit(NULL);
        }
        printf("worker got a task!\n");
        int netfd = pthreadPool->taskQueue.pfront->fd;
        Dequeue(&pthreadPool->taskQueue);
        pthread_mutex_unlock(&pthreadPool->mutex);
        
        MYSQL* mysql = mysql_init(NULL);
        // 连接上数据库
        MYSQL* Mret = mysql_real_connect(mysql, "localhost", "root", "654321",
                                         "client", 0, NULL, 0);
        MYSQL_CONNECT_CHECK(Mret, mysql);
        
        char name[128] = {0};
        int ret = login(netfd, name, mysql);
        LOG_CHECK("login", name);
        
        // 所有用户初始目录都为他们的根目录
        int curr_folder = getCurrFolder(name, mysql);
        printf("curr_folder = %d\n", curr_folder);

        tran_t working_dir;
        char msg[4096] = {0};
        
        while(1){
            // 每次执行操作前先把工作目录发送给客户端
            bzero(&working_dir, sizeof(working_dir));
            pwd(working_dir.data, curr_folder, mysql);
            working_dir.length = strlen(working_dir.data);
            printf("pwd = %s\n", working_dir.data);
            send(netfd, &working_dir, sizeof(int)+working_dir.length, MSG_NOSIGNAL);

            // 接收客户端的命令和参数
            int operat = 0;
            int arg_length;

            // 接收命令
            ret = recvn(netfd, &operat, sizeof(int));
            if(ret == 0){
                break;
            }
            printf("operate = %d\n", operat);

            // 接收参数
            recvn(netfd, &arg_length, sizeof(int));
            char* arg = (char*)malloc(arg_length + 1);
            ERROR_CHECK(arg, NULL, "malloc");
            recvn(netfd, arg, arg_length);
            arg[arg_length] = '\0';
            
            if(arg[0] != '\0'){
                arg[arg_length - 1] = '\0'; 
            }

            int ret = 0;
            switch(operat){
            case 0:
                ret = cdFunc(name, arg, &curr_folder, mysql);
                LOG_CHECK("cd", arg);
                error_send(ret, netfd);
                break;

            case 1:
                bzero(msg, sizeof(msg));
                ret = ls(msg, name, arg, curr_folder, mysql);
                LOG_CHECK("ls", arg);
                func_send(ret, netfd, msg);
                break;

            case 2:
                ret = putsTextFunc(name, arg, netfd, mysql, curr_folder);
                LOG_CHECK("puts", arg);
                break;

            case 3:
                ret = getsFunc(name, arg, curr_folder, netfd, mysql);
                LOG_CHECK("gets", arg);
                break;

            case 4:
                ret = removeFunc(curr_folder, arg, name, mysql);
                LOG_CHECK("remove", arg);
                error_send(ret, netfd);
                break;

            case 5:
                bzero(msg, sizeof(msg));
                ret = pwd(msg, curr_folder, mysql);
                LOG_CHECK("pwd", arg);
                func_send(ret, netfd, msg);
                break;

            case 6:
                ret = mkdirFunc(curr_folder, arg, name, mysql);
                LOG_CHECK("mkdir", arg);
                error_send(ret, netfd);
                break;

            case 7:
                ret = rmdirFunc(curr_folder, arg, name, mysql);
                LOG_CHECK("rmdir", arg);
                error_send(ret, netfd);
                break;
                
            default:
                send(netfd, &ret, sizeof(int), MSG_NOSIGNAL);
            }
            
            free(arg);
        }
        mysql_close(mysql);
        close(netfd);
    }
}
//void unlock(void *arg){
//    threadPool_t * pthreadPool = (threadPool_t *)arg;
//    pthread_mutex_unlock(&pthreadPool->mutex);
//}
//void *threadFunc(void * arg){
//    threadPool_t * pthreadPool = (threadPool_t *)arg;
//    while(1){
//        // 取出任务
//        int netfd;
//        pthread_mutex_lock(&pthreadPool->mutex);
//        pthread_cleanup_push(unlock,pthreadPool);
//        while(pthreadPool->taskQueue.queueSize == 0){
//            pthread_cond_wait(&pthreadPool->cond,&pthreadPool->mutex);
//        }
//        printf("worker got a task!\n");
//        netfd = pthreadPool->taskQueue.pfront->fd;
//        Dequeue(&pthreadPool->taskQueue);
//        //pthread_mutex_unlock(&pthreadPool->mutex);
//        pthread_cleanup_pop(1);
//        
//        transFile(netfd);
//        close(netfd);
//    }
//}
int makeWorker(threadPool_t *pthreadPool){
    for(int i = 0; i < pthreadPool->workerNum; ++i){
        pthread_create(&pthreadPool->tidArr[i],NULL,threadFunc,pthreadPool);
    }
    return 0;
}
